﻿%define pg.RootNamespace ParserGenerator
%define pg.SyntacticAnalysisNamespace ParserGenerator.Languages.MSIL
%define pg.SourceContextNamespace ParserGenerator.Input
%define pg.OutputNamespace ParserGenerator.Output

%define pg.AllowAutoDefineLiteralTokens False
%define pg.UsePythonLikeIndentation False
%define pg.indented False

%define pg.parser.classname MSILProgramParser
%define pg.parser.namespace ParserGenerator.Languages.MSIL

%define pg.parser.usings (
    ParserGenerator.Collections,
)


%token '('
%token ')'
%token '['
%token ']'
%token '{'
%token '}'
%token '<'
%token '>'
%token ','
%token '.'
%token '...'
%token '='
%token '+'
%token '*'
%token '*('
%token '/'
%token '&'
%token '!'

# 《ISO CLI 2012》（ISO／IEC 23271）P492 ILAsm keywords
%token '#line'
%token '.addon'
%token '.assembly'
%token '.base'
%token '.cctor'
%token '.class'
%token '.corflags'
%token '.ctor'
%token '.custom'
%token '.data'
%token '.emitbyte'
%token '.entrypoint'
%token '.event'
%token '.export'
%token '.field'
%token '.file'
%token '.fire'
%token '.get'
%token '.hash'
%token '.imagebase'
%token '.import'
%token '.language'
%token '.line'
%token '.locale'
%token '.localized'
%token '.locals'
%token '.manifestres'
%token '.maxstack'
%token '.method'
%token '.module'
%token '.mresource'
%token '.namespace'
%token '.nester'
%token '.other'
%token '.override'
%token '.pack'
%token '.param'
%token '.pdirect'
%token '.permission'
%token '.permissionset'
%token '.property'
%token '.publickey'
%token '.publickeytoken'
%token '.removeon'
%token '.set'
%token '.size'
%token '.subsystem'
%token '.this'
%token '.try'
%token '.ver'
%token '.vtable'
%token '.vtentry'
%token '.vtfixup'
%token '.zeroinit'
%token 'abstract'
%token 'add'
%token 'add.ovf'
%token 'add.ovf.un'
%token 'algorithm'
%token 'alignment'
%token 'and'
%token 'ansi'
%token 'any'
%token 'arglist'
%token 'array'
%token 'as'
%token 'assembly'
%token 'assert'
%token 'at'
%token 'auto'
%token 'autochar'
%token 'beforefieldinit'
%token 'beq'
%token 'beq.s'
%token 'bge'
%token 'bge.s'
%token 'bge.un'
%token 'bge.un.s'
%token 'bgt'
%token 'bgt.s'
%token 'bgt.un'
%token 'bgt.un.s'
%token 'ble'
%token 'ble.s'
%token 'ble.un'
%token 'ble.un.s'
%token 'blob'
%token 'blob_object'
%token 'blt'
%token 'blt.s'
%token 'blt.un'
%token 'blt.un.s'
%token 'bne.un'
%token 'bne.un.s'
%token 'bool'
%token 'box'
%token 'br'
%token 'br.s'
%token 'break'
%token 'brfalse'
%token 'brfalse.s'
%token 'brinst'
%token 'brinst.s'
%token 'brnull'
%token 'brnull.s'
%token 'brtrue'
%token 'brtrue.s'
%token 'brzero'
%token 'brzero.s'
%token 'bstr'
%token 'bytearray'
%token 'byvalstr'
%token 'call'
%token 'callconv'
%token 'calli'
%token 'callmostderived'
%token 'callvirt'
%token 'carray'
%token 'castclass'
%token 'catch'
%token 'cdecl'
%token 'ceq'
%token 'cf'
%token 'cgt'
%token 'cgt.un'
%token 'char'
%token 'cil'
%token 'ckfinite'
%token 'class'
%token 'clsid'
%token 'clt'
%token 'clt.un'
%token 'const'
%token 'constrained.'
%token 'conv.i'
%token 'conv.i1'
%token 'conv.i2'
%token 'conv.i4'
%token 'conv.i8'
%token 'conv.ovf.i'
%token 'conv.ovf.i.un'
%token 'conv.ovf.i1'
%token 'conv.ovf.i1.un'
%token 'conv.ovf.i2'
%token 'conv.ovf.i2.un'
%token 'conv.ovf.i4'
%token 'conv.ovf.i4.un'
%token 'conv.ovf.i8'
%token 'conv.ovf.i8.un'
%token 'conv.ovf.u'
%token 'conv.ovf.u.un'
%token 'conv.ovf.u1'
%token 'conv.ovf.u1.un'
%token 'conv.ovf.u2'
%token 'conv.ovf.u2.un'
%token 'conv.ovf.u4'
%token 'conv.ovf.u4.un'
%token 'conv.ovf.u8'
%token 'conv.ovf.u8.un'
%token 'conv.r.un'
%token 'conv.r4'
%token 'conv.r8'
%token 'conv.u'
%token 'conv.u1'
%token 'conv.u2'
%token 'conv.u4'
%token 'conv.u8'
%token 'cpblk'
%token 'cpobj'
%token 'currency'
%token 'custom'
%token 'date'
%token 'decimal'
%token 'default'
%token 'demand'
%token 'deny'
%token 'div'
%token 'div.un'
%token 'dup'
%token 'endfault'
%token 'endfilter'
%token 'endfinally'
%token 'endmac'
%token 'enum'
%token 'error'
%token 'explicit'
%token 'extends'
%token 'extern'
%token 'false'
%token 'famandassem'
%token 'family'
%token 'famorassem'
%token 'fastcall'
%token 'fault'
%token 'field'
%token 'filetime'
%token 'filter'
%token 'final'
%token 'finally'
%token 'fixed'
%token 'float'
%token 'float32'
%token 'float64'
%token 'forwardref'
%token 'fromunmanaged'
%token 'handler'
%token 'hidebysig'
%token 'hresult'
%token 'idispatch'
%token 'iidparam'
%token 'il'
%token 'illegal'
%token 'implements'
%token 'implicitcom'
%token 'implicitres'
%token 'import'
%token 'in'
%token 'inheritcheck'
%token 'init'
%token 'initblk'
%token 'initobj'
%token 'initonly'
%token 'instance'
%token 'int'
%token 'int16'
%token 'int32'
%token 'int64'
%token 'int8'
%token 'interface'
%token 'internalcall'
%token 'isinst'
%token 'iunknown'
%token 'jmp'
%token 'lasterr'
%token 'lcid'
%token 'ldarg'
%token 'ldarg.0'
%token 'ldarg.1'
%token 'ldarg.2'
%token 'ldarg.3'
%token 'ldarg.s'
%token 'ldarga'
%token 'ldarga.s'
%token 'ldc.i4'
%token 'ldc.i4.0'
%token 'ldc.i4.1'
%token 'ldc.i4.2'
%token 'ldc.i4.3'
%token 'ldc.i4.4'
%token 'ldc.i4.5'
%token 'ldc.i4.6'
%token 'ldc.i4.7'
%token 'ldc.i4.8'
%token 'ldc.i4.M1'
%token 'ldc.i4.m1'
%token 'ldc.i4.s'
%token 'ldc.i8'
%token 'ldc.r4'
%token 'ldc.r8'
%token 'ldelem'
%token 'ldelem.i'
%token 'ldelem.i1'
%token 'ldelem.i2'
%token 'ldelem.i4'
%token 'ldelem.i8'
%token 'ldelem.r4'
%token 'ldelem.r8'
%token 'ldelem.ref'
%token 'ldelem.u1'
%token 'ldelem.u2'
%token 'ldelem.u4'
%token 'ldelem.u8'
%token 'ldelema'
%token 'ldfld'
%token 'ldflda'
%token 'ldftn'
%token 'ldind.i'
%token 'ldind.i1'
%token 'ldind.i2'
%token 'ldind.i4'
%token 'ldind.i8'
%token 'ldind.r4'
%token 'ldind.r8'
%token 'ldind.ref'
%token 'ldind.u1'
%token 'ldind.u2'
%token 'ldind.u4'
%token 'ldind.u8'
%token 'ldlen'
%token 'ldloc'
%token 'ldloc.0'
%token 'ldloc.1'
%token 'ldloc.2'
%token 'ldloc.3'
%token 'ldloc.s'
%token 'ldloca'
%token 'ldloca.s'
%token 'ldnull'
%token 'ldobj'
%token 'ldsfld'
%token 'ldsflda'
%token 'ldstr'
%token 'ldtoken'
%token 'ldvirtftn'
%token 'leave'
%token 'leave.s'
%token 'linkcheck'
%token 'literal'
%token 'localloc'
%token 'lpstr'
%token 'lpstruct'
%token 'lptstr'
%token 'lpvoid'
%token 'lpwstr'
%token 'managed'
%token 'marshal'
%token 'mdtoken'
%token 'method'
%token 'mkrefany'
%token 'modopt'
%token 'modreq'
%token 'mul'
%token 'mul.ovf'
%token 'mul.ovf.un'
%token 'native'
%token 'neg'
%token 'nested'
%token 'newarr'
%token 'newobj'
%token 'newslot'
%token 'noappdomain'
%token 'no.'
%token 'noinlining'
%token 'nomachine'
%token 'nomangle'
%token 'nometadata'
%token 'noncasdemand'
%token 'noncasinheritance'
%token 'noncaslinkdemand'
%token 'nop'
%token 'noprocess'
%token 'not'
%token 'not_in_gc_heap'
%token 'notremotable'
%token 'notserialized'
%token 'null'
%token 'nullref'
%token 'object'
%token 'objectref'
%token 'opt'
%token 'optil'
%token 'or'
%token 'out'
%token 'permitonly'
%token 'pinned'
%token 'pinvokeimpl'
%token 'pop'
%token 'prefix1'
%token 'prefix2'
%token 'prefix3'
%token 'prefix4'
%token 'prefix5'
%token 'prefix6'
%token 'prefix7'
%token 'prefixref'
%token 'prejitdeny'
%token 'prejitgrant'
%token 'preservesig'
%token 'private'
%token 'privatescope'
%token 'protected'
%token 'public'
%token 'readonly.'
%token 'record'
%token 'refany'
%token 'refanytype'
%token 'refanyval'
%token 'rem'
%token 'rem.un'
%token 'reqmin'
%token 'reqopt'
%token 'reqrefuse'
%token 'reqsecobj'
%token 'request'
%token 'ret'
%token 'rethrow'
%token 'retval'
%token 'rtspecialname'
%token 'runtime'
%token 'safearray'
%token 'sealed'
%token 'sequential'
%token 'serializable'
%token 'shl'
%token 'shr'
%token 'shr.un'
%token 'sizeof'
%token 'special'
%token 'specialname'
%token 'starg'
%token 'starg.s'
%token 'static'
%token 'stdcall'
%token 'stelem'
%token 'stelem.i'
%token 'stelem.i1'
%token 'stelem.i2'
%token 'stelem.i4'
%token 'stelem.i8'
%token 'stelem.r4'
%token 'stelem.r8'
%token 'stelem.ref'
%token 'stfld'
%token 'stind.i'
%token 'stind.i1'
%token 'stind.i2'
%token 'stind.i4'
%token 'stind.i8'
%token 'stind.r4'
%token 'stind.r8'
%token 'stind.ref'
%token 'stloc'
%token 'stloc.0'
%token 'stloc.1'
%token 'stloc.2'
%token 'stloc.3'
%token 'stloc.s'
%token 'stobj'
%token 'storage'
%token 'stored_object'
%token 'stream'
%token 'streamed_object'
%token 'string'
%token 'struct'
%token 'stsfld'
%token 'sub'
%token 'sub.ovf'
%token 'sub.ovf.un'
%token 'switch'
%token 'synchronized'
%token 'syschar'
%token 'sysstring'
%token 'tail.'
%token 'tbstr'
%token 'thiscall'
%token 'throw'
%token 'tls'
%token 'to'
%token 'true'
%token 'typedref'
%token 'uint'
%token 'uint8'
%token 'uint16'
%token 'uint32'
%token 'uint64'
%token 'unaligned.'
%token 'unbox'
%token 'unbox.any'
%token 'unicode'
%token 'unmanaged'
%token 'unmanagedexp'
%token 'unsigned'
%token 'unused'
%token 'userdefined'
%token 'value'
%token 'valuetype'
%token 'vararg'
%token 'variant'
%token 'vector'
%token 'virtual'
%token 'void'
%token 'volatile.'
%token 'wchar'
%token 'winapi'
%token 'with'
%token 'wrapper'
%token 'xor'




# TODO: fix
#%keyword KeywordAbstract ('abstract')


%shift '['

%token Identifier ("identifier") : Identifier
%token SingleQuoteLiteral ("single quote literal") : SingleQuoteLiteral
%token DoubleQuoteLiteral ("double quote literal") : DoubleQuoteLiteral
%token Int32Literal ("int32 literal") : Int32Literal
%token Int64Literal ("int64 literal") : Int64Literal

%token TypedefAliasType (".typedef alias type") : TypedefAliasType
%token TypedefAliasClassName (".typedef alias class name") : TypedefAliasClassName

%goal Type

Identifier = (name : string)
TypedefAliasType = (name : DottedName)
TypedefAliasClassName = (name : DottedName)
SingleQuoteLiteral = (value : string)
DoubleQuoteLiteral = (value : string)
CompoundQuoteLiteral = (items : [DoubleQuoteLiteral]+)
Int32Literal = (value : int32, isHexadecimal : bool?)
Int64Literal = (value : int64, isHexadecimal : bool?)
NonNegativeInt32Literal = (value : int32*, isHexadecimal : bool?)
MetadataToken = (value : Int32Literal)


# 《.NET IL Assembler》（Lidin）P394 Identifier Nonterminals
Name:
    Identifier (name : Identifier)
    SingleQuoteLiteral (name : SingleQuoteLiteral)
DottedName:
    Simple (name : Name)
    Compound (operand : DottedName, member : Name)
SlashedName:
    Simple (name : DottedName)
    Compound (operand : SlashedName, member : DottedName)

# 《.NET IL Assembler》（Lidin）P394 Class Referencing
ClassName:
    DottedAssembly (assembly : DottedName, name : SlashedName)
    MetadataTokenAssembly (assembly : MetadataToken, name : SlashedName)
    StarAssembly (name : SlashedName)
    DottedModule (module : DottedName, name : SlashedName)
    SlashedName (name : SlashedName)
    MetadataToken (token : MetadataToken)
    TypedefAliasClassName (name : TypedefAliasClassName)
    This
    Base
    Nester

# 《ISO CLI 2012》（ISO／IEC 23271）P526 type
# 《.NET IL Assembler》（Lidin）P397 Managed Types in Signatures
Type:
    NamedClass (name : ClassName)
    NamedValueClass (name : ClassName)
    NamedValuetype (name : ClassName)
    NumericTypeParameterReference (number : NonNegativeInt32Literal)
    NumericMethodTypeParameterReference (number : NonNegativeInt32Literal)
    NamedTypeParameterReference (name : DottedName)
    NamedMethodTypeParameterReference (name : DottedName)
    MethodPointer (callConvention : CallConvention?, returnType : Type, formalParameters : FormalParameterList?)
    Object
    TypedReference
    String
    Void
    Char
    Bool
    Int8
    Int16
    Int32
    Int64
    Float32
    Float64
    UnsignedInt8
    UnsignedInt16
    UnsignedInt32
    UnsignedInt64
    UInt8
    UInt16
    UInt32
    UInt64
    NativeInt
    NativeUnsignedInt
    NativeUInt
    NativeFloat
    TypedefAliasType (name : TypedefAliasType)
    GenericInstantiation (operand : Type, typeArguments : TypeArgumentList?)
    Array (operand : Type, bounds : ArrayBounds?)
    FixedValuetypeArray (operand : Type, length : NonNegativeInt32Literal)
    RequiredModified (operand : Type, qualifier : ClassName)
    OptionalModified (operand : Type, qualifier : ClassName)
    ManagedPointer (operand : Type)
    UnmanagedPointer (operand : Type)
    Pinned (operand : Type)
ArrayBounds = (bounds : [ArrayBound]+)
ArrayBound:
    Ellipsis
    Fixed (length : NonNegativeInt32Literal)
    LowerUpper (lower : Int32Literal, upper : Int32Literal)
    Lower (lower : Int32Literal)
TypeSpecification:
    ClassName (name : ClassName)
    DottedName (name : DottedName)
    ModuleDottedName (name : DottedName)
    Type (`type` : Type)

# 《ISO CLI 2012》（ISO／IEC 23271）P525 nativeType
# 《.NET IL Assembler》（Lidin）P398 Native Types in Marshaling Signatures
NativeType:
    QuadCustom (item1 : CompoundQuoteLiteral, item2 : CompoundQuoteLiteral, item3 : CompoundQuoteLiteral, item4 : CompoundQuoteLiteral)
    Custom (item1 : CompoundQuoteLiteral, item2 : CompoundQuoteLiteral)
    Variant
    Currency
    SysChar
    Void
    Bool
    Int8
    Int16
    Int32
    Int64
    Float32
    Float64
    UnsignedInt8
    UnsignedInt16
    UnsignedInt32
    UnsignedInt64
    UInt8
    UInt16
    UInt32
    UInt64
    Error
    Decimal
    Date
    BSTR
    LPSTR
    LPWSTR
    LPTSTR
    ObjectReference
    IUnknown (index : InterfaceIdParameterIndex?)
    IDispatch (index : InterfaceIdParameterIndex?)
    Struct
    Interface (index : InterfaceIdParameterIndex?)
    SafeArray (element : VariantType, descriptor : CompoundQuoteLiteral?)
    Int
    UnsignedInt
    UInt
    NestedStruct
    ByValString
    AnsiBSTR
    TBSTR
    VariantBool
    Method
    AsAny
    LPStruct
    TypedefAliasType (name : TypedefAliasType)
    Pointer (operand : NativeType)
    Array (operand : NativeType, length : NonNegativeInt32Literal?, extra : NonNegativeInt32Literal?)
    FixedSysString (length : NonNegativeInt32Literal)
    FixedArray (length : NonNegativeInt32Literal, operand : NativeType)
InterfaceIdParameterIndex = (number : NonNegativeInt32Literal)
VariantType:
    Null
    Variant
    Currency
    Void
    Bool
    Int8
    Int16
    Int32
    Int64
    Float32
    Float64
    UnsignedInt8
    UnsignedInt16
    UnsignedInt32
    UnsignedInt64
    UInt8
    UInt16
    UInt32
    UInt64
    Pointer
    Decimal
    Date
    BSTR
    LPSTR
    LPWSTR
    IUnknown
    IDispatch
    SafeArray
    Int
    UnsignedInt
    UInt
    Error
    HRESULT
    CArray
    UserDefined
    Record
    FileTime
    Blob
    Stream
    Storage
    StreamedObject
    StoredObject
    BlobObject
    ClassFactory
    CLSID
    Array (operand : VariantType)
    Vector (operand : VariantType)
    Reference (operand : VariantType)


# 《.NET IL Assembler》（Lidin）P400 Method and Field Referencing
CallConvention:
    Instance (operand : CallConvention?)
    Explicit (operand : CallConvention?)
    Default
    Vararg
    Cdecl
    Stdcall
    ThisCall
    FastCall
    Numeric (number : Int32Literal)
TypeArgumentList = (items : [Type]+)
FormalParameterList = (items : [FormalParameter]+)
FormalParameter:
    Ellipsis
    Normal (`attributes` : FormalParameterAttributeList?, `type` : Type, marshal : MarshalClause?, name : Name?)




# 《.NET IL Assembler》（Lidin）P403 Field Declaration
MarshalClause = (`type` : NativeType)




# 《.NET IL Assembler》（Lidin）P404 Method Declaration
FormalParameterAttributeList = (items : [FormalParameterAttribute]+)
FormalParameterAttribute:
    In
    Out
    Optional
    Numeric (number : Int32Literal)





%%


# 《.NET IL Assembler》（Lidin）P393 Data Type Nonterminals
CompoundQuoteLiteral as CompoundQuoteLiteral:
    DoubleQuoteLiteral %+ '+' => CompoundQuoteLiteral.New($1, @@)
NonNegativeInt32Literal as NonNegativeInt32Literal:
    Int32Literal => CheckNonNegativeInt32Literal($1)
MetadataToken as MetadataToken:
    'mdtoken' '(' Int32Literal ')' => MetadataToken.New($3, @@)

# 《.NET IL Assembler》（Lidin）P394 Identifier Nonterminals
Name as Name:
    Identifier => Name.NewIdentifier($1, @@)
    SingleQuoteLiteral => Name.NewSingleQuoteLiteral($1, @@)
DottedName as DottedName:
    Name => DottedName.NewSimple($1, @@)
    DottedName '.' Name => DottedName.NewCompound($1, $3, @@)
SlashedName as SlashedName:
    DottedName => SlashedName.NewSimple($1, @@)
    SlashedName '/' DottedName => SlashedName.NewCompound($1, $3, @@)

# 《.NET IL Assembler》（Lidin）P394 Class Referencing
ClassName as ClassName:
    '[' DottedName ']' SlashedName => ClassName.NewDottedAssembly($2, $4, @@)
    '[' MetadataToken ']' SlashedName => ClassName.NewMetadataTokenAssembly($2, $4, @@)
    '[' '*' ']' SlashedName => ClassName.NewStarAssembly($4, @@)
    '[' '.module' DottedName ']' SlashedName => ClassName.NewDottedModule($3, $5, @@)
    SlashedName => ClassName.NewSlashedName($1, @@)
    MetadataToken => ClassName.NewMetadataToken($1, @@)
    TypedefAliasClassName => ClassName.NewTypedefAliasClassName($1, @@)
    '.this' => ClassName.NewThis(@@)
    '.base' => ClassName.NewBase(@@)
    '.nester' => ClassName.NewNester(@@)

# 《.NET IL Assembler》（Lidin）P397 Managed Types in Signatures
# 《ISO CLI 2012》（ISO／IEC 23271）P526 type
PrimaryType as Type:
    'class' ClassName => Type.NewNamedClass($2, @@)
    'value' 'class' ClassName => Type.NewNamedValueClass($3, @@)
    'valuetype' ClassName => Type.NewNamedValuetype($2, @@)
    '!' NonNegativeInt32Literal => Type.NewNumericTypeParameterReference($2, @@)
    '!' '!' NonNegativeInt32Literal => Type.NewNumericMethodTypeParameterReference($3, @@)
    '!' DottedName => Type.NewNamedTypeParameterReference($2, @@)
    '!' '!' DottedName => Type.NewNamedMethodTypeParameterReference($3, @@)
    'method' CallConvention? Type '*(' FormalParameterList? ')' => Type.NewMethodPointer($2, $3, $5, @@)
    'object' => Type.NewObject(@@)
    'typedref' => Type.NewTypedReference(@@)
    'string' => Type.NewString(@@)
    'void' => Type.NewVoid(@@)
    'char' => Type.NewChar(@@)
    'bool' => Type.NewBool(@@)
    'int8' => Type.NewInt8(@@)
    'int16' => Type.NewInt16(@@)
    'int32' => Type.NewInt32(@@)
    'int64' => Type.NewInt64(@@)
    'float32' => Type.NewFloat32(@@)
    'float64' => Type.NewFloat64(@@)
    'unsigned' 'int8' => Type.NewUnsignedInt8(@@)
    'unsigned' 'int16' => Type.NewUnsignedInt16(@@)
    'unsigned' 'int32' => Type.NewUnsignedInt32(@@)
    'unsigned' 'int64' => Type.NewUnsignedInt64(@@)
    'uint8' => Type.NewUInt8(@@)
    'uint16' => Type.NewUInt16(@@)
    'uint32' => Type.NewUInt32(@@)
    'uint64' => Type.NewUInt64(@@)
    'native' 'int' => Type.NewNativeInt(@@)
    'native' 'unsigned' 'int' => Type.NewNativeUnsignedInt(@@)
    'native' 'uint' => Type.NewNativeUInt(@@)
    'native' 'float' => Type.NewNativeFloat(@@)
    TypedefAliasType => Type.NewTypedefAliasType($1, @@)
    PrimaryType '<' TypeArgumentList? '>' => Type.NewGenericInstantiation($1, $3, @@)
    PrimaryType '[' ArrayBounds? ']' => Type.NewArray($1, $3, @@)
    PrimaryType 'value' '[' NonNegativeInt32Literal ']' => Type.NewFixedValuetypeArray($1, $4, @@)
    PrimaryType 'modreq' '(' ClassName ')' => Type.NewRequiredModified($1, $4, @@)
    PrimaryType 'modopt' '(' ClassName ')' => Type.NewOptionalModified($1, $4, @@)
    PrimaryType '&' => Type.NewManagedPointer($1, @@)
    PrimaryType '*' => Type.NewUnmanagedPointer($1, @@)
    PrimaryType 'pinned' => Type.NewPinned($1, @@)
Type as Type:
    PrimaryType => $1
ArrayBounds as ArrayBounds:
    ArrayBound %+ ',' => ArrayBounds.New($1, @@)
ArrayBound as ArrayBound:
    '...' => ArrayBound.NewEllipsis(@@)
    NonNegativeInt32Literal => ArrayBound.NewFixed($1, @@)
    Int32Literal '...' Int32Literal => ArrayBound.NewLowerUpper($1, $3, @@)
    Int32Literal '...' => ArrayBound.NewLower($1, @@)
TypeSpecification as TypeSpecification:
    ClassName => TypeSpecification.NewClassName($1, @@)
    '[' DottedName ']' => TypeSpecification.NewDottedName($2, @@)
    '[' '.module' DottedName ']' => TypeSpecification.NewModuleDottedName($3, @@)
    Type => TypeSpecification.NewType($1, @@)

# 《.NET IL Assembler》（Lidin）P398 Native Types in Marshaling Signatures
# 《ISO CLI 2012》（ISO／IEC 23271）P525 nativeType
PrimaryNativeType as NativeType:
    'custom' '(' CompoundQuoteLiteral ',' CompoundQuoteLiteral ',' CompoundQuoteLiteral ',' CompoundQuoteLiteral ')' => NativeType.NewQuadCustom($3, $5, $7, $9, @@)
    'custom' '(' CompoundQuoteLiteral ',' CompoundQuoteLiteral ')' => NativeType.NewCustom($3, $5, @@)
    'variant' => NativeType.NewVariant(@@)
    'currency' => NativeType.NewCurrency(@@)
    'syschar' => NativeType.NewSysChar(@@)
    'void' => NativeType.NewVoid(@@)
    'bool' => NativeType.NewBool(@@)
    'int8' => NativeType.NewInt8(@@)
    'int16' => NativeType.NewInt16(@@)
    'int32' => NativeType.NewInt32(@@)
    'int64' => NativeType.NewInt64(@@)
    'float32' => NativeType.NewFloat32(@@)
    'float64' => NativeType.NewFloat64(@@)
    'unsigned' 'int8' => NativeType.NewUnsignedInt8(@@)
    'unsigned' 'int16' => NativeType.NewUnsignedInt16(@@)
    'unsigned' 'int32' => NativeType.NewUnsignedInt32(@@)
    'unsigned' 'int64' => NativeType.NewUnsignedInt64(@@)
    'uint8' => NativeType.NewUInt8(@@)
    'uint16' => NativeType.NewUInt16(@@)
    'uint32' => NativeType.NewUInt32(@@)
    'uint64' => NativeType.NewUInt64(@@)
    'error' => NativeType.NewError(@@)
    'decimal' => NativeType.NewDecimal(@@)
    'date' => NativeType.NewDate(@@)
    'bstr' => NativeType.NewBSTR(@@)
    'lpstr' => NativeType.NewLPSTR(@@)
    'lpwstr' => NativeType.NewLPWSTR(@@)
    'lptstr' => NativeType.NewLPTSTR(@@)
    'objectref' => NativeType.NewObjectReference(@@)
    'iunknown' InterfaceIdParameterIndex? => NativeType.NewIUnknown($2, @@)
    'idispatch' InterfaceIdParameterIndex? => NativeType.NewIDispatch($2, @@)
    'struct' => NativeType.NewStruct(@@)
    'interface' InterfaceIdParameterIndex? => NativeType.NewInterface($2, @@)
    'safearray' VariantType => NativeType.NewSafeArray($2, None, @@)
    'safearray' VariantType ',' CompoundQuoteLiteral => NativeType.NewSafeArray($2, $4, @@)
    'int' => NativeType.NewInt(@@)
    'unsigned' 'int' => NativeType.NewUnsignedInt(@@)
    'uint' => NativeType.NewUInt(@@)
    'nested' 'struct' => NativeType.NewNestedStruct(@@)
    'byvalstr' => NativeType.NewByValString(@@)
    'ansi' 'bstr' => NativeType.NewAnsiBSTR(@@)
    'tbstr' => NativeType.NewTBSTR(@@)
    'variant' 'bool' => NativeType.NewVariantBool(@@)
    'method' => NativeType.NewMethod(@@)
    'as' 'any' => NativeType.NewAsAny(@@)
    'lpstruct' => NativeType.NewLPStruct(@@)
    TypedefAliasType => NativeType.NewTypedefAliasType($1, @@)
    PrimaryNativeType '*' => NativeType.NewPointer($1, @@)
    PrimaryNativeType '[' ']' => NativeType.NewArray($1, None, None, @@)
    PrimaryNativeType '[' NonNegativeInt32Literal ']' => NativeType.NewArray($1, $3, None, @@)
    PrimaryNativeType '[' NonNegativeInt32Literal '+' NonNegativeInt32Literal ']' => NativeType.NewArray($1, $3, $5, @@)
    PrimaryNativeType '[' '+' NonNegativeInt32Literal ']' => NativeType.NewArray($1, None, $4, @@)
    'fixed' 'sysstring' '[' NonNegativeInt32Literal ']' => NativeType.NewFixedSysString($4, @@)
NativeType as NativeType:
    PrimaryNativeType => $1
    'fixed' 'array' '[' NonNegativeInt32Literal ']' NativeType => NativeType.NewFixedArray($4, $6, @@)
InterfaceIdParameterIndex as InterfaceIdParameterIndex:
    '(' 'iidparam' '=' NonNegativeInt32Literal ')' => InterfaceIdParameterIndex.New($4, @@)
PrimaryVariantType as VariantType:
    'null' => VariantType.NewNull(@@)
    'variant' => VariantType.NewVariant(@@)
    'currency' => VariantType.NewCurrency(@@)
    'void' => VariantType.NewVoid(@@)
    'bool' => VariantType.NewBool(@@)
    'int8' => VariantType.NewInt8(@@)
    'int16' => VariantType.NewInt16(@@)
    'int32' => VariantType.NewInt32(@@)
    'int64' => VariantType.NewInt64(@@)
    'float32' => VariantType.NewFloat32(@@)
    'float64' => VariantType.NewFloat64(@@)
    'unsigned' 'int8' => VariantType.NewUnsignedInt8(@@)
    'unsigned' 'int16' => VariantType.NewUnsignedInt16(@@)
    'unsigned' 'int32' => VariantType.NewUnsignedInt32(@@)
    'unsigned' 'int64' => VariantType.NewUnsignedInt64(@@)
    'uint8' => VariantType.NewUInt8(@@)
    'uint16' => VariantType.NewUInt16(@@)
    'uint32' => VariantType.NewUInt32(@@)
    'uint64' => VariantType.NewUInt64(@@)
    '*' => VariantType.NewPointer(@@)
    'decimal' => VariantType.NewDecimal(@@)
    'date' => VariantType.NewDate(@@)
    'bstr' => VariantType.NewBSTR(@@)
    'lpstr' => VariantType.NewLPSTR(@@)
    'lpwstr' => VariantType.NewLPWSTR(@@)
    'iunknown' => VariantType.NewIUnknown(@@)
    'idispatch' => VariantType.NewIDispatch(@@)
    'safearray' => VariantType.NewSafeArray(@@)
    'int' => VariantType.NewInt(@@)
    'unsigned' 'int' => VariantType.NewUnsignedInt(@@)
    'uint' => VariantType.NewUInt(@@)
    'error' => VariantType.NewError(@@)
    'hresult' => VariantType.NewHRESULT(@@)
    'carray' => VariantType.NewCArray(@@)
    'userdefined' => VariantType.NewUserDefined(@@)
    'record' => VariantType.NewRecord(@@)
    'filetime' => VariantType.NewFileTime(@@)
    'blob' => VariantType.NewBlob(@@)
    'stream' => VariantType.NewStream(@@)
    'storage' => VariantType.NewStorage(@@)
    'streamed_object' => VariantType.NewStreamedObject(@@)
    'stored_object' => VariantType.NewStoredObject(@@)
    'blob_object' => VariantType.NewBlobObject(@@)
    'cf' => VariantType.NewClassFactory(@@)
    'clsid' => VariantType.NewCLSID(@@)
    PrimaryVariantType '[' ']' => VariantType.NewArray($1, @@)
    PrimaryVariantType 'vector' => VariantType.NewVector($1, @@)
    PrimaryVariantType '&' => VariantType.NewReference($1, @@)
VariantType as VariantType:
    PrimaryVariantType => $1

# 《.NET IL Assembler》（Lidin）P400 Method and Field Referencing
CallConvention as CallConvention:
    'instance' CallConvention? => CallConvention.NewInstance($2, @@)
    'explicit' CallConvention? => CallConvention.NewExplicit($2, @@)
    'default' => CallConvention.NewDefault(@@)
    'vararg' => CallConvention.NewVararg(@@)
    'unmanaged' 'cdecl' => CallConvention.NewCdecl(@@)
    'unmanaged' 'stdcall' => CallConvention.NewStdcall(@@)
    'unmanaged' 'thiscall' => CallConvention.NewThisCall(@@)
    'unmanaged' 'fastcall' => CallConvention.NewFastCall(@@)
    'callconv' '(' Int32Literal ')' => CallConvention.NewNumeric($3, @@)
TypeArgumentList as TypeArgumentList:
    Type %+ ',' => TypeArgumentList.New($1, @@)
FormalParameterList as FormalParameterList:
    FormalParameter %+ ',' => FormalParameterList.New($1, @@)
FormalParameter as FormalParameter:
    '...' => FormalParameter.NewEllipsis(@@)
    FormalParameterAttributeList? Type MarshalClause? Name? => FormalParameter.NewNormal($1, $2, $3, $4, @@)

# 《.NET IL Assembler》（Lidin）P403 Field Declaration
MarshalClause as MarshalClause:
    'marshal' '(' NativeType ')' => MarshalClause.New($3, @@)

# 《.NET IL Assembler》（Lidin）P404 Method Declaration
FormalParameterAttributeList as FormalParameterAttributeList:
    FormalParameterAttribute+ => FormalParameterAttributeList.New($1, @@)
FormalParameterAttribute as FormalParameterAttribute:
    '[' 'in' ']' => FormalParameterAttribute.NewIn(@@)
    '[' 'out' ']' => FormalParameterAttribute.NewOut(@@)
    '[' 'opt' ']' => FormalParameterAttribute.NewOptional(@@)
    '[' Int32Literal ']' => FormalParameterAttribute.NewNumeric($2, @@)





%%

nl = [ '\n' '\v' '\f' '\r' '\x85' '\u2028' '\u2029' ]
ws = [ '\t' ' ' '\xa0' '\u2000'-'\u200a' '\u202f' '\u205f' '\u3000' ]+
nnl = [^ '\n' '\v' '\f' '\r' '\x85' '\u2028' '\u2029' ]

lower      = ['a'-'z']
upper      = ['A'-'Z']
digit      = ['0'-'9']
letter     = lower | upper | '_'
identifier = letter (letter | digit)*

decimal_integer = digit+
hexadecimal_integer = '0x' ['0'-'9' 'A'-'F' 'a'-'f']+

<*>:
    nl =>: pass
    ws =>: pass

    '(' => '('
    ')' => ')'
    '[' => '['
    ']' => ']'
    '{' => '{'
    '}' => '}'
    '<' => '<'
    '>' => '>'
    ',' => ','
    '.' => '.'
    '...' => '...'
    '=' => '='
    '+' => '+'
    '*' => '*'
    '*(' => '*('
    '/' => '/'
    '&' => '&'
    '!' => '!'

    # 《ISO CLI 2012》（ISO／IEC 23271）P492 ILAsm keywords
    '#line' => '#line'
    '.addon' => '.addon'
    '.assembly' => '.assembly'
    '.base' => '.base'
    '.cctor' => '.cctor'
    '.class' => '.class'
    '.corflags' => '.corflags'
    '.ctor' => '.ctor'
    '.custom' => '.custom'
    '.data' => '.data'
    '.emitbyte' => '.emitbyte'
    '.entrypoint' => '.entrypoint'
    '.event' => '.event'
    '.export' => '.export'
    '.field' => '.field'
    '.file' => '.file'
    '.fire' => '.fire'
    '.get' => '.get'
    '.hash' => '.hash'
    '.imagebase' => '.imagebase'
    '.import' => '.import'
    '.language' => '.language'
    '.line' => '.line'
    '.locale' => '.locale'
    '.localized' => '.localized'
    '.locals' => '.locals'
    '.manifestres' => '.manifestres'
    '.maxstack' => '.maxstack'
    '.method' => '.method'
    '.module' => '.module'
    '.mresource' => '.mresource'
    '.namespace' => '.namespace'
    '.nester' => '.nester'
    '.other' => '.other'
    '.override' => '.override'
    '.pack' => '.pack'
    '.param' => '.param'
    '.pdirect' => '.pdirect'
    '.permission' => '.permission'
    '.permissionset' => '.permissionset'
    '.property' => '.property'
    '.publickey' => '.publickey'
    '.publickeytoken' => '.publickeytoken'
    '.removeon' => '.removeon'
    '.set' => '.set'
    '.size' => '.size'
    '.subsystem' => '.subsystem'
    '.this' => '.this'
    '.try' => '.try'
    '.ver' => '.ver'
    '.vtable' => '.vtable'
    '.vtentry' => '.vtentry'
    '.vtfixup' => '.vtfixup'
    '.zeroinit' => '.zeroinit'
    'abstract' => 'abstract'
    'add' => 'add'
    'add.ovf' => 'add.ovf'
    'add.ovf.un' => 'add.ovf.un'
    'algorithm' => 'algorithm'
    'alignment' => 'alignment'
    'and' => 'and'
    'ansi' => 'ansi'
    'any' => 'any'
    'arglist' => 'arglist'
    'array' => 'array'
    'as' => 'as'
    'assembly' => 'assembly'
    'assert' => 'assert'
    'at' => 'at'
    'auto' => 'auto'
    'autochar' => 'autochar'
    'beforefieldinit' => 'beforefieldinit'
    'beq' => 'beq'
    'beq.s' => 'beq.s'
    'bge' => 'bge'
    'bge.s' => 'bge.s'
    'bge.un' => 'bge.un'
    'bge.un.s' => 'bge.un.s'
    'bgt' => 'bgt'
    'bgt.s' => 'bgt.s'
    'bgt.un' => 'bgt.un'
    'bgt.un.s' => 'bgt.un.s'
    'ble' => 'ble'
    'ble.s' => 'ble.s'
    'ble.un' => 'ble.un'
    'ble.un.s' => 'ble.un.s'
    'blob' => 'blob'
    'blob_object' => 'blob_object'
    'blt' => 'blt'
    'blt.s' => 'blt.s'
    'blt.un' => 'blt.un'
    'blt.un.s' => 'blt.un.s'
    'bne.un' => 'bne.un'
    'bne.un.s' => 'bne.un.s'
    'bool' => 'bool'
    'box' => 'box'
    'br' => 'br'
    'br.s' => 'br.s'
    'break' => 'break'
    'brfalse' => 'brfalse'
    'brfalse.s' => 'brfalse.s'
    'brinst' => 'brinst'
    'brinst.s' => 'brinst.s'
    'brnull' => 'brnull'
    'brnull.s' => 'brnull.s'
    'brtrue' => 'brtrue'
    'brtrue.s' => 'brtrue.s'
    'brzero' => 'brzero'
    'brzero.s' => 'brzero.s'
    'bstr' => 'bstr'
    'bytearray' => 'bytearray'
    'byvalstr' => 'byvalstr'
    'call' => 'call'
    'callconv' => 'callconv'
    'calli' => 'calli'
    'callmostderived' => 'callmostderived'
    'callvirt' => 'callvirt'
    'carray' => 'carray'
    'castclass' => 'castclass'
    'catch' => 'catch'
    'cdecl' => 'cdecl'
    'ceq' => 'ceq'
    'cf' => 'cf'
    'cgt' => 'cgt'
    'cgt.un' => 'cgt.un'
    'char' => 'char'
    'cil' => 'cil'
    'ckfinite' => 'ckfinite'
    'class' => 'class'
    'clsid' => 'clsid'
    'clt' => 'clt'
    'clt.un' => 'clt.un'
    'const' => 'const'
    'constrained.' => 'constrained.'
    'conv.i' => 'conv.i'
    'conv.i1' => 'conv.i1'
    'conv.i2' => 'conv.i2'
    'conv.i4' => 'conv.i4'
    'conv.i8' => 'conv.i8'
    'conv.ovf.i' => 'conv.ovf.i'
    'conv.ovf.i.un' => 'conv.ovf.i.un'
    'conv.ovf.i1' => 'conv.ovf.i1'
    'conv.ovf.i1.un' => 'conv.ovf.i1.un'
    'conv.ovf.i2' => 'conv.ovf.i2'
    'conv.ovf.i2.un' => 'conv.ovf.i2.un'
    'conv.ovf.i4' => 'conv.ovf.i4'
    'conv.ovf.i4.un' => 'conv.ovf.i4.un'
    'conv.ovf.i8' => 'conv.ovf.i8'
    'conv.ovf.i8.un' => 'conv.ovf.i8.un'
    'conv.ovf.u' => 'conv.ovf.u'
    'conv.ovf.u.un' => 'conv.ovf.u.un'
    'conv.ovf.u1' => 'conv.ovf.u1'
    'conv.ovf.u1.un' => 'conv.ovf.u1.un'
    'conv.ovf.u2' => 'conv.ovf.u2'
    'conv.ovf.u2.un' => 'conv.ovf.u2.un'
    'conv.ovf.u4' => 'conv.ovf.u4'
    'conv.ovf.u4.un' => 'conv.ovf.u4.un'
    'conv.ovf.u8' => 'conv.ovf.u8'
    'conv.ovf.u8.un' => 'conv.ovf.u8.un'
    'conv.r.un' => 'conv.r.un'
    'conv.r4' => 'conv.r4'
    'conv.r8' => 'conv.r8'
    'conv.u' => 'conv.u'
    'conv.u1' => 'conv.u1'
    'conv.u2' => 'conv.u2'
    'conv.u4' => 'conv.u4'
    'conv.u8' => 'conv.u8'
    'cpblk' => 'cpblk'
    'cpobj' => 'cpobj'
    'currency' => 'currency'
    'custom' => 'custom'
    'date' => 'date'
    'decimal' => 'decimal'
    'default' => 'default'
    'demand' => 'demand'
    'deny' => 'deny'
    'div' => 'div'
    'div.un' => 'div.un'
    'dup' => 'dup'
    'endfault' => 'endfault'
    'endfilter' => 'endfilter'
    'endfinally' => 'endfinally'
    'endmac' => 'endmac'
    'enum' => 'enum'
    'error' => 'error'
    'explicit' => 'explicit'
    'extends' => 'extends'
    'extern' => 'extern'
    'false' => 'false'
    'famandassem' => 'famandassem'
    'family' => 'family'
    'famorassem' => 'famorassem'
    'fastcall' => 'fastcall'
    'fault' => 'fault'
    'field' => 'field'
    'filetime' => 'filetime'
    'filter' => 'filter'
    'final' => 'final'
    'finally' => 'finally'
    'fixed' => 'fixed'
    'float' => 'float'
    'float32' => 'float32'
    'float64' => 'float64'
    'forwardref' => 'forwardref'
    'fromunmanaged' => 'fromunmanaged'
    'handler' => 'handler'
    'hidebysig' => 'hidebysig'
    'hresult' => 'hresult'
    'idispatch' => 'idispatch'
    'iidparam' => 'iidparam'
    'il' => 'il'
    'illegal' => 'illegal'
    'implements' => 'implements'
    'implicitcom' => 'implicitcom'
    'implicitres' => 'implicitres'
    'import' => 'import'
    'in' => 'in'
    'inheritcheck' => 'inheritcheck'
    'init' => 'init'
    'initblk' => 'initblk'
    'initobj' => 'initobj'
    'initonly' => 'initonly'
    'instance' => 'instance'
    'int' => 'int'
    'int16' => 'int16'
    'int32' => 'int32'
    'int64' => 'int64'
    'int8' => 'int8'
    'interface' => 'interface'
    'internalcall' => 'internalcall'
    'isinst' => 'isinst'
    'iunknown' => 'iunknown'
    'jmp' => 'jmp'
    'lasterr' => 'lasterr'
    'lcid' => 'lcid'
    'ldarg' => 'ldarg'
    'ldarg.0' => 'ldarg.0'
    'ldarg.1' => 'ldarg.1'
    'ldarg.2' => 'ldarg.2'
    'ldarg.3' => 'ldarg.3'
    'ldarg.s' => 'ldarg.s'
    'ldarga' => 'ldarga'
    'ldarga.s' => 'ldarga.s'
    'ldc.i4' => 'ldc.i4'
    'ldc.i4.0' => 'ldc.i4.0'
    'ldc.i4.1' => 'ldc.i4.1'
    'ldc.i4.2' => 'ldc.i4.2'
    'ldc.i4.3' => 'ldc.i4.3'
    'ldc.i4.4' => 'ldc.i4.4'
    'ldc.i4.5' => 'ldc.i4.5'
    'ldc.i4.6' => 'ldc.i4.6'
    'ldc.i4.7' => 'ldc.i4.7'
    'ldc.i4.8' => 'ldc.i4.8'
    'ldc.i4.M1' => 'ldc.i4.M1'
    'ldc.i4.m1' => 'ldc.i4.m1'
    'ldc.i4.s' => 'ldc.i4.s'
    'ldc.i8' => 'ldc.i8'
    'ldc.r4' => 'ldc.r4'
    'ldc.r8' => 'ldc.r8'
    'ldelem' => 'ldelem'
    'ldelem.i' => 'ldelem.i'
    'ldelem.i1' => 'ldelem.i1'
    'ldelem.i2' => 'ldelem.i2'
    'ldelem.i4' => 'ldelem.i4'
    'ldelem.i8' => 'ldelem.i8'
    'ldelem.r4' => 'ldelem.r4'
    'ldelem.r8' => 'ldelem.r8'
    'ldelem.ref' => 'ldelem.ref'
    'ldelem.u1' => 'ldelem.u1'
    'ldelem.u2' => 'ldelem.u2'
    'ldelem.u4' => 'ldelem.u4'
    'ldelem.u8' => 'ldelem.u8'
    'ldelema' => 'ldelema'
    'ldfld' => 'ldfld'
    'ldflda' => 'ldflda'
    'ldftn' => 'ldftn'
    'ldind.i' => 'ldind.i'
    'ldind.i1' => 'ldind.i1'
    'ldind.i2' => 'ldind.i2'
    'ldind.i4' => 'ldind.i4'
    'ldind.i8' => 'ldind.i8'
    'ldind.r4' => 'ldind.r4'
    'ldind.r8' => 'ldind.r8'
    'ldind.ref' => 'ldind.ref'
    'ldind.u1' => 'ldind.u1'
    'ldind.u2' => 'ldind.u2'
    'ldind.u4' => 'ldind.u4'
    'ldind.u8' => 'ldind.u8'
    'ldlen' => 'ldlen'
    'ldloc' => 'ldloc'
    'ldloc.0' => 'ldloc.0'
    'ldloc.1' => 'ldloc.1'
    'ldloc.2' => 'ldloc.2'
    'ldloc.3' => 'ldloc.3'
    'ldloc.s' => 'ldloc.s'
    'ldloca' => 'ldloca'
    'ldloca.s' => 'ldloca.s'
    'ldnull' => 'ldnull'
    'ldobj' => 'ldobj'
    'ldsfld' => 'ldsfld'
    'ldsflda' => 'ldsflda'
    'ldstr' => 'ldstr'
    'ldtoken' => 'ldtoken'
    'ldvirtftn' => 'ldvirtftn'
    'leave' => 'leave'
    'leave.s' => 'leave.s'
    'linkcheck' => 'linkcheck'
    'literal' => 'literal'
    'localloc' => 'localloc'
    'lpstr' => 'lpstr'
    'lpstruct' => 'lpstruct'
    'lptstr' => 'lptstr'
    'lpvoid' => 'lpvoid'
    'lpwstr' => 'lpwstr'
    'managed' => 'managed'
    'marshal' => 'marshal'
    'mdtoken' => 'mdtoken'
    'method' => 'method'
    'mkrefany' => 'mkrefany'
    'modopt' => 'modopt'
    'modreq' => 'modreq'
    'mul' => 'mul'
    'mul.ovf' => 'mul.ovf'
    'mul.ovf.un' => 'mul.ovf.un'
    'native' => 'native'
    'neg' => 'neg'
    'nested' => 'nested'
    'newarr' => 'newarr'
    'newobj' => 'newobj'
    'newslot' => 'newslot'
    'noappdomain' => 'noappdomain'
    'no.' => 'no.'
    'noinlining' => 'noinlining'
    'nomachine' => 'nomachine'
    'nomangle' => 'nomangle'
    'nometadata' => 'nometadata'
    'noncasdemand' => 'noncasdemand'
    'noncasinheritance' => 'noncasinheritance'
    'noncaslinkdemand' => 'noncaslinkdemand'
    'nop' => 'nop'
    'noprocess' => 'noprocess'
    'not' => 'not'
    'not_in_gc_heap' => 'not_in_gc_heap'
    'notremotable' => 'notremotable'
    'notserialized' => 'notserialized'
    'null' => 'null'
    'nullref' => 'nullref'
    'object' => 'object'
    'objectref' => 'objectref'
    'opt' => 'opt'
    'optil' => 'optil'
    'or' => 'or'
    'out' => 'out'
    'permitonly' => 'permitonly'
    'pinned' => 'pinned'
    'pinvokeimpl' => 'pinvokeimpl'
    'pop' => 'pop'
    'prefix1' => 'prefix1'
    'prefix2' => 'prefix2'
    'prefix3' => 'prefix3'
    'prefix4' => 'prefix4'
    'prefix5' => 'prefix5'
    'prefix6' => 'prefix6'
    'prefix7' => 'prefix7'
    'prefixref' => 'prefixref'
    'prejitdeny' => 'prejitdeny'
    'prejitgrant' => 'prejitgrant'
    'preservesig' => 'preservesig'
    'private' => 'private'
    'privatescope' => 'privatescope'
    'protected' => 'protected'
    'public' => 'public'
    'readonly.' => 'readonly.'
    'record' => 'record'
    'refany' => 'refany'
    'refanytype' => 'refanytype'
    'refanyval' => 'refanyval'
    'rem' => 'rem'
    'rem.un' => 'rem.un'
    'reqmin' => 'reqmin'
    'reqopt' => 'reqopt'
    'reqrefuse' => 'reqrefuse'
    'reqsecobj' => 'reqsecobj'
    'request' => 'request'
    'ret' => 'ret'
    'rethrow' => 'rethrow'
    'retval' => 'retval'
    'rtspecialname' => 'rtspecialname'
    'runtime' => 'runtime'
    'safearray' => 'safearray'
    'sealed' => 'sealed'
    'sequential' => 'sequential'
    'serializable' => 'serializable'
    'shl' => 'shl'
    'shr' => 'shr'
    'shr.un' => 'shr.un'
    'sizeof' => 'sizeof'
    'special' => 'special'
    'specialname' => 'specialname'
    'starg' => 'starg'
    'starg.s' => 'starg.s'
    'static' => 'static'
    'stdcall' => 'stdcall'
    'stelem' => 'stelem'
    'stelem.i' => 'stelem.i'
    'stelem.i1' => 'stelem.i1'
    'stelem.i2' => 'stelem.i2'
    'stelem.i4' => 'stelem.i4'
    'stelem.i8' => 'stelem.i8'
    'stelem.r4' => 'stelem.r4'
    'stelem.r8' => 'stelem.r8'
    'stelem.ref' => 'stelem.ref'
    'stfld' => 'stfld'
    'stind.i' => 'stind.i'
    'stind.i1' => 'stind.i1'
    'stind.i2' => 'stind.i2'
    'stind.i4' => 'stind.i4'
    'stind.i8' => 'stind.i8'
    'stind.r4' => 'stind.r4'
    'stind.r8' => 'stind.r8'
    'stind.ref' => 'stind.ref'
    'stloc' => 'stloc'
    'stloc.0' => 'stloc.0'
    'stloc.1' => 'stloc.1'
    'stloc.2' => 'stloc.2'
    'stloc.3' => 'stloc.3'
    'stloc.s' => 'stloc.s'
    'stobj' => 'stobj'
    'storage' => 'storage'
    'stored_object' => 'stored_object'
    'stream' => 'stream'
    'streamed_object' => 'streamed_object'
    'string' => 'string'
    'struct' => 'struct'
    'stsfld' => 'stsfld'
    'sub' => 'sub'
    'sub.ovf' => 'sub.ovf'
    'sub.ovf.un' => 'sub.ovf.un'
    'switch' => 'switch'
    'synchronized' => 'synchronized'
    'syschar' => 'syschar'
    'sysstring' => 'sysstring'
    'tail.' => 'tail.'
    'tbstr' => 'tbstr'
    'thiscall' => 'thiscall'
    'throw' => 'throw'
    'tls' => 'tls'
    'to' => 'to'
    'true' => 'true'
    'typedref' => 'typedref'
    'uint' => 'uint'
    'uint8' => 'uint8'
    'uint16' => 'uint16'
    'uint32' => 'uint32'
    'uint64' => 'uint64'
    'unaligned.' => 'unaligned.'
    'unbox' => 'unbox'
    'unbox.any' => 'unbox.any'
    'unicode' => 'unicode'
    'unmanaged' => 'unmanaged'
    'unmanagedexp' => 'unmanagedexp'
    'unsigned' => 'unsigned'
    'unused' => 'unused'
    'userdefined' => 'userdefined'
    'value' => 'value'
    'valuetype' => 'valuetype'
    'vararg' => 'vararg'
    'variant' => 'variant'
    'vector' => 'vector'
    'virtual' => 'virtual'
    'void' => 'void'
    'volatile.' => 'volatile.'
    'wchar' => 'wchar'
    'winapi' => 'winapi'
    'with' => 'with'
    'wrapper' => 'wrapper'
    'xor' => 'xor'

    identifier =>: ScanIdentifierName(); yield Identifier
    decimal_integer =>:
        ScanIntegerValue(false, 10)
        if TokenValue :? Int64Literal:
            yield Int64Literal
        yield Int32Literal
    '-' decimal_integer =>:
        ScanIntegerValue(true, 10)
        if TokenValue :? Int64Literal:
            yield Int64Literal
        yield Int32Literal
    hexadecimal_integer =>:
        ScanIntegerValue(false, 16)
        if TokenValue :? Int64Literal:
            yield Int64Literal
        yield Int32Literal
    '-' hexadecimal_integer =>:
        ScanIntegerValue(true, 16)
        if TokenValue :? Int64Literal:
            yield Int64Literal
        yield Int32Literal
